/*
 * @Author: your name
 * @Date: 2020-09-18 10:00:20
 * @LastEditTime: 2021-04-19 10:43:52
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \tower_defense_demo\assets\scripts\game_scene.ts
 */

import { SoundMgr } from "./sound_mgr"
import { UG } from "./modules/ugame"
import LoadingDoor from "./loading_door"
import Enemy from "./game_scene/enemy/enemy"
import { LEVELDATA1 } from "./game_data/level_data/level_data_1";
import { EnemyAttr } from "./game_data/enemy_data/enemy_data";

const { ccclass, property } = cc._decorator;

@ccclass
export default class GameScene extends cc.Component {

    @property(cc.Prefab)    // 敌人预制体
    public enemy_pre_arr: cc.Prefab[] = [];
    @property(cc.Prefab)    // 关卡地图预制体
    public map_pre_arr: cc.Prefab[] = [];

    // 节点
    @property(LoadingDoor)  // 加载门
    public loading_door: LoadingDoor = null;
    @property(cc.Node)      // 关卡成功界面
    public success_panel_node: cc.Node = null;
    @property(cc.Node)      // 关卡失败界面
    public fail_panel_node: cc.Node = null;

    @property(cc.Node)      // 地图节点
    public map_panel_node: cc.Node = null;
    @property(cc.Node)      // 子弹节点
    public bullet_root_node: cc.Node = null;
    @property(cc.Node)      // 敌人存放的根节点
    public enemy_root_node: cc.Node = null;

    @property(cc.Label)     // 血量label
    public blood_label: cc.Label = null;
    @property(cc.Label)     // 血量label
    public uchip_label: cc.Label = null;
    @property(cc.Label)     // 血量label
    public round_label: cc.Label = null;

    @property(cc.ProgressBar)   // 闪电技能冷却bar
    public lightning_pro_bar: cc.ProgressBar = null;

    // 技能魔法阵预制体
    @property(cc.Prefab)    // 魔法阵预制体
    public magic_circle_pre: cc.Prefab = null;

    // 地图中保存塔的节点
    public map_tag_root: cc.Node = null;

    // 
    public go_back: boolean = false;
    public blood: number = 0;   // 血量
    public game_started: boolean = false;
    public finish_gen_enemy: boolean = false;   // 敌人生成完毕标志
    public map_level: number = undefined;       // 当前地图级别
    public level_data = undefined;              // 关卡怪物数据

    public cur_round: number = 0;       // 当前第几波怪物
    public cur_road_index: number = 0;  // 当前选择的路径索引
    public cur_gen_total: number = 0;   // 当前这波产生怪物的总数
    public cur_gen_now: number = 0;     // 当前这波已产生怪物数量

    public cur_schedule_time: number = 0;   // 当前延时器延迟时间

    public lightning_cooling_time: number = 5;  // 闪电冷却时间
    public lightning_count_time: number = 0;
    public lightning_is_ok: boolean = true;    

    onLoad() {
        // 播放背景音乐
        // SoundMgr.play_music("sounds/music/game_bg1", true);
        this.blood = 0;
        this.game_started = false;
        UG.is_game_paused = false;
        UG.clear_enemy_arr();

        let map_level: number = UG.get_cur_level();
        if (map_level >= this.map_pre_arr.length) {
            map_level = this.map_pre_arr.length - 1;
        }
        // 根据关卡生成游戏地图
        // let game_map_node: cc.Node = cc.instantiate(this.map_pre_arr[0]);
        let game_map_node: cc.Node = cc.instantiate(this.map_pre_arr[1]);
        game_map_node.parent = this.map_panel_node;
        // 获得地图中塔节点
        this.map_tag_root = game_map_node.getChildByName("tag_panel");
    }

    public start_game(): void {
        if (this.game_started) {
            cc.log('游戏已经开始');
            return;
        }

        // 清空操作
        this.finish_gen_enemy = false;
        UG.clear_enemy_arr();   // 清空敌人集合
        this.unscheduleAllCallbacks();

        this.game_started = true;
        UG.is_game_started = true;

        // 同步用户信息
        const cur_user = UG.get_cur_user();
        this.blood = cur_user.blood;
        this.blood_label.string = this.blood.toString();
        this.uchip_label.string = UG.get_uchip().toString();

        // 生成第一波怪物
        this.map_level = UG.get_cur_level();
        let map_level = this.map_level;
        if (map_level >= this.map_pre_arr.length) {
            map_level = this.map_pre_arr.length - 1;
        }

        // 暂时默认都是第一关的数据
        this.level_data = LEVELDATA1;
        this.round_label.string = "round 0 / " + this.level_data.length;
        this.cur_round = 0;
        this.cur_road_index = 0;
        this.cur_gen_total = 0;
        this.cur_gen_now = 0;
        this.gen_round_enemy();
    }

    // 生成一波怪物
    public gen_round_enemy(): void {
        // 判断敌人是都已经产生完毕
        if (this.cur_round >= this.level_data.length) {
            this.finish_gen_enemy = true;
            // 判断是否过关
            this.scheduleOnce(this.pass_level.bind(this), 1);
            return;
        }
        // if (this.cur_round >= 1) {
        //     this.finish_gen_enemy = true;
        //     // 判断是否过关
        //     return;
        // }
        const cur_round_params = this.level_data[this.cur_round];
        let time: number = cur_round_params.delay;
        const num: number = cur_round_params.num;

        this.cur_gen_total = num;
        this.cur_gen_now = 0;

        // 产生敌人
        this.cur_road_index = 0;
        time = time + cur_round_params.gen_time_set[this.cur_gen_now];
        this.cur_schedule_time = time;
        this.scheduleOnce(this.gen_one_enemy.bind(this), time);
        return;
    }

    // 生成一个怪物
    public gen_one_enemy(): void {
        // 获取必要参数
        const cur_round_params = this.level_data[this.cur_round];
        const type = cur_round_params.type[this.cur_gen_now];
        const road_set = cur_round_params.road_set;
        const enemy_params = EnemyAttr[type];

        // 地图数据
        const map_road_data = UG.get_map_road_data();
        // 生成敌人
        let enemy_node: cc.Node = cc.instantiate(this.enemy_pre_arr[type]);
        let enemy_com: Enemy = enemy_node.getComponent(Enemy);
        enemy_com.init_enemy(enemy_params);

        enemy_node.parent = this.enemy_root_node;
        UG.add_enemy(enemy_node);
        let index: number = 0;  // 当前怪物跑的路径索引
        if (cur_round_params.random_road) {
            let random_index = Math.random() * road_set.length; // [0, road_set.length]
            random_index = Math.floor(random_index);
            if (random_index >= road_set.length) {
                random_index = road_set.length - 1;
            }
            index = road_set[random_index];
        } else {
            index = this.cur_road_index;
            this.cur_road_index++;
            if (this.cur_road_index >= road_set.length) {
                this.cur_road_index = 0;
            }
            index = road_set[index];
        }
        if (index >= map_road_data.length) {
            index = 0;
        }
        let enemy: Enemy = enemy_node.getComponent(Enemy);
        let road_data = map_road_data[index];
        enemy.gen_at_road(road_data);

        // 
        if (this.cur_gen_now === 0) {
            this.round_label.string = "round " + (this.cur_round + 1).toString() + " / " + this.level_data.length;
        }

        this.cur_gen_now++;
        // 放下一波敌人
        if (this.cur_gen_now == this.cur_gen_total) {
            this.cur_round++;
            this.gen_round_enemy();
        } else {
            const time: number = cur_round_params.gen_time_set[this.cur_gen_now];
            this.cur_schedule_time = time;
            this.scheduleOnce(this.gen_one_enemy.bind(this), time);
        }
    }

    // 关门 加载
    public close_door(): void {
        this.loading_door.set_door_state(0);     // 0关门，1开门
        this.scheduleOnce(() => {
            // 开门
            this.loading_door.open_the_door(null);
        }, 0.1);
    }

    // 跳转到home场景
    public goto_roadmap_scene(): void {
        if (this.go_back) {
            return;
        }
        // 播放音效
        SoundMgr.play_effect("sounds/click");

        this.go_back = true;
        this.loading_door.close_the_door(() => {
            cc.director.loadScene("roadmap_scene", () => {
                let roadmap_scene = cc.find("Canvas/roadmap_scene").getComponent("roadmap_scene");
                roadmap_scene.close_door();
            })
        })
    }

    // 显示用户金币数
    public show_game_uchip(): void {
        this.uchip_label.string = UG.get_uchip().toString()
    }

    // 点击事件，主动技能 --> 闪电
    public on_skill_lightning_btn_click(e): void {
        if (!this.lightning_is_ok) {
            return;
        }
        // 先清空
        let skills_panel_node: cc.Node = cc.find('Canvas/skills_root');
        skills_panel_node.removeAllChildren();
        // 1 生成魔法阵
        let magic_circle_node: cc.Node = cc.instantiate(this.magic_circle_pre);
        magic_circle_node.parent = skills_panel_node;
        let click_pos: cc.Vec2 = e.getLocation();
        let v2: cc.Vec2 = skills_panel_node.convertToNodeSpaceAR(click_pos);
        magic_circle_node.setScale(1, 1);
        magic_circle_node.setPosition(v2);
    }

    // 敌人攻击玩家
    public on_player_attacked(hurt: number): void {
        if (!this.game_started) {
            return;
        }
        this.blood -= hurt;
        if (this.blood <= 0) {  // 游戏结束
            this.blood = 0;
            this.game_started = false;
            UG.is_game_started = false;
            cc.log('game over');
            this.success_panel_node.active = false;
            this.fail_panel_node.active = true;
        }
        this.blood_label.string = this.blood.toString();
    }

    // 通关判断
    public pass_level(): void {
        if (!this.game_started || !this.finish_gen_enemy || UG.enemy_arr.length > 0) {
            this.scheduleOnce(this.pass_level.bind(this), 1);
            return;
        }
        // 通关
        this.game_started = false;
        this.fail_panel_node.active = false;
        this.success_panel_node.active = true;

        const cur_user: any = UG.get_cur_user();
        const cur_level: number = UG.get_cur_level();

        // 评价
        let score: number = 1;
        let total_blood: number = cur_user.blood;

        if (this.blood > (2 * total_blood) / 3) {   // 剩余血量超过三分之二
            score = 3;
        } else if (this.blood > total_blood / 3) {    // 三分之一
            score = 2;
        } else {
            score = 1;
        }

        if (score > cur_user.level_info[cur_level]) {
            let add_star_num: number = score - cur_user.level_info[cur_level];
            cur_user.level_info[cur_level] = score;
            cur_user.star_num += add_star_num;

            // 同步数据
            UG.user_data[UG.cur_user] = cur_user;
            UG.sync_user_data();
        }
    }

    // update中判断技能冷却更新时间
    update(dt) {
        // 技能是好的，不需要冷却
        if (this.lightning_is_ok) {
            return;
        }    
        if (this.lightning_count_time >= this.lightning_cooling_time) { // 冷却完成
            this.lightning_is_ok = true;
            this.lightning_count_time = 0;
        } else {
            this.lightning_count_time += dt;
            this.lightning_pro_bar.progress = 1 - this.lightning_count_time / this.lightning_cooling_time;
        }
    }
}
